import Cesium from 'cesium';
/**
 * 坡度分析-单点分析坡度
 * @create zgf
 */

class SlopeAnalyser {
  handler:any;
  id:any;
  viewer:any;
  helperTips:any;
  entitiesArr:any;
  centerPoint:any;
  centerPointWorldTerrain:any;
  centerPointEntity:any;
  isHasState:any;
  resultPoints:any;
  options:any;
  czPoints:any;
  isDrawingEnd:any;
  isAnalysisEnd:any;
  constructor(viewer:any) {
    //鼠标事件
    //this.mouseManager = new mouseManager(viewer);
    this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
    this.id = Cesium.createGuid();
    this.viewer = viewer;
    //单点中心点--（经度，纬度，高度）-在3dtiles上
    this.centerPoint = null;
    //在地形上的中心点
    this.centerPointWorldTerrain=null;
    //单点实体
    this.centerPointEntity = null;
    //是否设置过中心点
    this.isHasState = false;
    //包含中心点start-高程中心点，圆环上的点end-高程点，中心点和圆环的坡度angle
    this.resultPoints = [];
    this.options={};
    //所有的实体
    this.entitiesArr=[];
    //
    this.czPoints=[];
    this.isDrawingEnd=false;
    this.isAnalysisEnd=false;
  }

  /**
   * 初始化-鼠标mouse提示和点击中心点
   * @param radius  半径范围
   * @param yjSlope  预警坡度
   * @param wxSlope  威胁坡度
   */
  startAnalysis(radius:any,yjSlope:any,wxSlope:any) {
    this.isDrawingEnd=false;
    this.isAnalysisEnd=false;
    // this.remove();
    this.options={
      radius:radius,
      yjSlope:yjSlope,
      wxSlope:wxSlope
    }
    let _this = this;
    var info = "";
    // this.viewer.scene.globe.depthTestAgainstTerrain = true;
    if(!this.handler){
      this.handler=  new Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
    }
    _this.createHelper([-1000,-1000], info);

    //移动-主要是文字提示
    _this.handler.setInputAction(function (movement:any) {
      info = '请设置分析点';
      _this.updateHelper(movement.position,info)
    }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

    //点击-添加点-进行分析
    _this.handler.setInputAction(function (movement:any) {
      var cartesian = _this.viewer.scene.pickPosition(movement.position);
      if (!cartesian) {
        const ellipsoid = _this.viewer.scene.globe.ellipsoid;
        cartesian = _this.viewer.scene.camera.pickEllipsoid(movement.position, ellipsoid);
      }
      if (_this.centerPointEntity) (
        _this.viewer.entities.remove(_this.centerPointEntity)
      )
      _this.isDrawingEnd=true;
      _this.centerPointEntity = _this.viewer.entities.add({
        position: cartesian,
        ellipsoid: {
          radii: new Cesium.Cartesian3(0.6, 0.6, 0.6),
          material: Cesium.Color.BLUE,
          // heightReference : Cesium.HeightReference.CLAMP_TO_GROUND,
        }
      });
      _this.entitiesArr.push(_this.centerPointEntity);
      //笛卡尔转经纬度

      _this.centerPoint = _this.Cartesian3ToLonlat(cartesian);

      if (_this.handler) {
        _this.handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
        _this.handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
        _this.removeHelper();
      }
      _this.getRadiusPoints(_this.centerPoint, _this.options['radius']);
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  }

  /**
   * 获取基于中心点的，以距离量测范围内的圆上的所有的点
   *  弧度： 角度 * Math.PI / 180
   */
  getRadiusPoints(centerPointm:any, radius:any) {
    let _this=this;
    let circlePoints = [];
    if (!centerPointm) {
      return;
    }
    var circle = new Cesium.CircleOutlineGeometry({
      center: Cesium.Cartesian3.fromDegrees(centerPointm['x'], centerPointm['y']),
      granularity:Math.PI / 2,
      radius: radius
    });
    var geometry = Cesium.CircleOutlineGeometry.createGeometry(circle);
    var list = geometry.attributes.position.values;
    //console.log("list.length",list.length);
    var pointsList=[];
    for (let i = 0; i < list.length; i++) {
      if (i % 3 === 0) {
        var index = i / 3;
        var point=this.Cartesian3ToLonlat(new Cesium.Cartesian3(list[index * 3], list[index * 3 + 1], list[index * 3 + 2]));
        pointsList.push(point);
      }
    }
    //console.log("pointsList",pointsList.length);
    //计算坡度
    _this.CalculateSlope(pointsList,0)
  }

  /**
   * 笛卡尔坐标转经纬度
   * @constructor
   */
  Cartesian3ToLonlat(Cartesian3:any){
    let cartographic = Cesium.Cartographic.fromCartesian(Cartesian3, this.viewer.scene.globe.ellipsoid, new Cesium.Cartographic());
    let lng = Cesium.Math.toDegrees(cartographic.longitude);//经度
    let lat = Cesium.Math.toDegrees(cartographic.latitude);//纬度
    let height = cartographic.height;
    return {
      x:lng,
      y:lat,
      z:height
    }
  }
  /**
   * 计算坡度值-勾股定理-
   * 角度 = 弧度 * 180 / Math.PI
   * @create zgf
   * @constructor
   */
  CalculateSlope(points:any,index:any) {
    if(points.length==0){
      return;
    }
    var startPoint=this.centerPoint;
    var startPointC=new Cesium.Cartesian3.fromDegrees(startPoint.x,startPoint.y,startPoint.z);
    var endPoint=points[index];
    var endPointC=new Cesium.Cartesian3.fromDegrees(endPoint.x,endPoint.y,endPoint.z+10000);
    var positions=[];
    //在2个点中间进行插值的个数
    var count=10;
    for (var i = 0; i <= count; i++) {
      positions.push(Cesium.Cartesian3.lerp(startPointC , endPointC , i / count, new Cesium.Cartesian3()));
    }
    this.viewer.scene.clampToHeightMostDetailed(positions).then((clampedCartesians)=> {
      // var czline=   this.viewer.entities.add({
      //     // id:Date.parse(new Date())+'single-slope',
      //     polyline : {
      //         positions :clampedCartesians,
      //         width : 10,
      //         arcType : Cesium.ArcType.NONE,
      //         material : new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED),
      //         // clampToGround :true, //折线贴地
      //     }
      // });
      // this.entitiesArr.push(czline);

      // 每个点的高度
      var height = [];
      for (var i = 0; i < count; ++i) {
        height.push(Cesium.Cartographic.fromCartesian(clampedCartesians[i]).height);
      }
      endPoint=this.Cartesian3ToLonlat(clampedCartesians[count-1]);
      var sinValue = (endPoint.z - startPoint.z) /
        Cesium.Cartesian3.distance(
          Cesium.Cartesian3.fromDegrees(startPoint.x, startPoint.y, startPoint.z),
          Cesium.Cartesian3.fromDegrees(endPoint.x, endPoint.y, endPoint.z)
        );
      // 根据sin得到弧度值
      var radian = Math.asin(sinValue);
      var angle = radian * 180 / Math.PI;
      //console.log(angle);
      this.addSlopeEntity(startPoint,endPoint,angle.toFixed(2));
      index=index+1;
      if(index<=points.length-1){
        this.CalculateSlope(points,index)
      }else{
        this.isAnalysisEnd=true;
      }
    })
  }
  addSlopeEntity(startPoint:any,endPoint:any,angle:any){
    var color=null;
    if(Math.abs(angle)>=this.options['yjSlope'] && Math.abs(angle)<this.options['wxSlope']){
      color=Cesium.Color.YELLOW;//预警
    }else if(Math.abs(angle)>=this.options['wxSlope']){
      color=Cesium.Color.RED;//威胁
    }else{
      return;
    }
    var startCartesian3=Cesium.Cartesian3.fromDegrees(startPoint['x'],startPoint['y'],startPoint['z']+0.1);
    var endCartesian3=Cesium.Cartesian3.fromDegrees(endPoint['x'],endPoint['y'],endPoint['z']+0.1);
    //添加箭头实体
    var en=   this.viewer.entities.add({
      // id:Date.parse(new Date())+'single-slope',
      polyline : {
        positions :[startCartesian3,endCartesian3],
        width : 10,
        arcType : Cesium.ArcType.NONE,
        material : new Cesium.PolylineArrowMaterialProperty(color),
        // clampToGround :true, //折线贴地
      }
    });
    this.entitiesArr.push(en);
    var text=angle <0 ? "-"+Math.abs(angle) : Math.abs(angle)+"";
    //添加文字实体
    var label= this.viewer.entities.add({
      position:endCartesian3,
      point: { //点
        pixelSize: 1,
        color: new Cesium.Color(0.0, 0.0, 0.0, 0.0)  //颜色设置透明
        // heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,
      },
      label: { //文字标签
        text: text+"°",
        font: '14pt monospace',
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        fillColor:Cesium.Color.RED,
        outlineColor:Cesium.Color.WHITE,
        outlineWidth: 5,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM, //垂直方向以底部来计算标签的位置
        pixelOffset: new Cesium.Cartesian2(0, -25) ,  //偏移量
        /*font: '14pt monospace',
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        fillColor:color,
        outlineColor:color,
        outlineWidth: 2,
        verticalOrigin: Cesium.VerticalOrigin.BOTTOM, //垂直方向以底部来计算标签的位置
        pixelOffset: new Cesium.Cartesian2(0, -25) ,  //偏移量*/
        // heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,
      },
    });
    this.entitiesArr.push(label);
  }

  /**
   * 移除当前添加的坡度实体
   * @create zgf
   */
  disponse() {
    if(this.entitiesArr.length==0){
      return;
    }
    for (let index = 0; index < this.entitiesArr.length; index++) {
      var element = this.entitiesArr[index];
      this.viewer.entities.remove(element);
    }
  }

  /**
   * 创建文字提示
   * @param screenPosition
   * @param text
   */
  createHelper(screenPosition: any, text: string) {
    this.helperTips = document.createElement('div');
    this.helperTips.innerText = text;
    this.helperTips.style.color = '#00FA9A';
    this.helperTips.style.position = 'fixed';
    this.helperTips.style.left = screenPosition['x'] + 'px';
    this.helperTips.style.top = screenPosition['y'] + 20 + 'px';
    this.helperTips.style.backgroundColor = '#FFFFFF';
    document.body.appendChild(this.helperTips);
  }

  /**
   * 更新文字提示
   * @param screenPosition
   * @param text
   */
  updateHelper(screenPosition: any, text: string) {
    this.helperTips.style.left = screenPosition['x'] + 'px';
    this.helperTips.style.top = screenPosition['y'] + 20 + 'px';
    this.helperTips.innerText = text;
  }

  removeHelper() {
    if(this.helperTips){
      this.helperTips.remove();
    }
  }

}
export default  SlopeAnalyser;
